<template>
  <div class="api-test-editor">
    <!-- 顶部标题栏 -->
    <div class="header" style="border-radius: 10px">
      <div class="header-left">
        <h1 class="title" v-if="!title_status">{{ title }}</h1>
        <el-input v-model="title" v-if="title_status"></el-input>
        <el-button
          type="primary"
          @click="title_status = !title_status"
          title="编辑"
          style="
            border-radius: 8px;
            margin-left: 5px;
            width: 10px;
            height: 10px;
          "
        >
          <el-icon><Edit /></el-icon>
        </el-button>
      </div>
      <div class="header-right">
        <el-button @click="handleReset" type="danger">重置</el-button>
        <el-button
          @click="moveStatus = !moveStatus"
          :type="moveStatus ? 'danger' : 'primary'"
          plain
        >
          {{ moveStatus ? '完成' : '排序' }}
        </el-button>
        <el-button @click="importDataStatus = true" type="primary">
          导入数据
        </el-button>
        <el-button @click="handleSave" type="primary">
          {{ route.query.caseModuleId ? '修改用例' : '保存用例' }}
        </el-button>
        <el-button @click="showDialog" type="success">预览数据</el-button>
      </div>
    </div>

    <div
      class="main-content"
      style="background-color: rgb(204, 214, 225, 0); border-radius: 10px"
    >
      <!-- 左侧HTTP方法面板 -->
      <div class="sidebar">
        <div class="sidebar-section">
          <div class="section-header">
            <span class="hollow-text gentle-blue">HTTP方法</span>
          </div>
          <div class="section-content">
            <div
              v-for="method in httpMethods"
              :key="method.type"
              class="method-item"
              :class="method.type"
              :style="{ background: method.color }"
              draggable="true"
              @dragstart="onDragStart(method)"
              @dragend="onDragEnd"
            >
              <span class="method-icon">{{ method.icon }}</span>
              <span class="method-name">{{ method.name }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧用例编辑区域 -->
      <div class="content">
        <div
          class="drop-zone"
          :class="{ 'drag-over': isDragOver, folded: LayOutSettingStore.fold }"
          @dragover="onDragOver"
          @dragleave="onDragLeave"
          @drop="onDrop"
        >
          <div class="zone-label" v-if="testCases.length === 0">
            <div class="label-icon">📋📋</div>
            <div class="label-text">将左侧HTTP方法拖拽到此处添加测试用例</div>
          </div>

          <!-- 用例表格 -->
          <div class="cases-table" v-if="testCases.length > 0">
            <div class="table-header">
              <div class="table-col" :style="{ width: width1 }">用例编号</div>
              <div class="table-col" :style="{ width: width2 }">用例模块</div>
              <div class="table-col" :style="{ width: width3 }">用例描述</div>
              <div class="table-col" :style="{ width: width4 }">用例标题</div>
              <div class="table-col" :style="{ width: width5 }">接口地址</div>
              <div class="table-col" :style="{ width: width6 }">是否执行</div>
              <div class="table-col" :style="{ width: width7 }">token操作</div>
              <div class="table-col" :style="{ width: width8 }">特殊请求头</div>
              <div class="table-col" :style="{ width: width9 }">请求方式</div>
              <div class="table-col" :style="{ width: width10 }">
                入参关键字
              </div>
              <div class="table-col" :style="{ width: width11 }">上传文件</div>
              <div class="table-col" :style="{ width: width11 }">请求参数</div>
              <div class="table-col" :style="{ width: width12 }">后置SQL</div>
              <div class="table-col" :style="{ width: width13 }">预期响应</div>
              <div class="table-col" :style="{ width: width14 }">预期结果</div>
              <div class="table-col" :style="{ width: width15 }">操作</div>
            </div>

            <div class="table-body">
              <div
                v-for="(testCase, index) in testCases"
                :key="testCase.id"
                class="table-row"
              >
                <div class="table-col" :style="{ width: width1 }">
                  <span class="cell-text1">
                    {{ testCase.caseId || '空' }}
                  </span>

                  <!-- <span class="cell-text">
                    case_{{ String(index + 1).padStart(3, '0') }}
                  </span> -->
                </div>
                <div class="table-col" :style="{ width: width2 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.module || '空' }}
                    </template>
                    <span class="cell-text">
                      {{ testCase.module || '空' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width3 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.description || '空' }}
                    </template>
                    <span class="cell-text">
                      {{ testCase.description || '空' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width4 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.title || '空' }}
                    </template>
                    <span class="cell-text">
                      {{ testCase.title || '空' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width5 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.apiUrl || '空' }}
                    </template>
                    <span class="cell-text url">
                      {{ testCase.apiUrl || '空' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width6 }">
                  <span class="cell-text">
                    {{ testCase.enabled ? '是' : '否' }}
                  </span>
                </div>
                <div class="table-col" :style="{ width: width7 }">
                  <span class="cell-text">
                    {{ testCase.tokenOperation || '读' }}
                  </span>
                </div>
                <div class="table-col" :style="{ width: width8 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.specialHeaders || '{}' }}
                    </template>
                    <span class="cell-text">
                      {{ testCase.specialHeaders || '{}' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width9 }">
                  <span class="cell-text method" :class="testCase.method">
                    {{ testCase.method }}
                  </span>
                </div>
                <div class="table-col" :style="{ width: width10 }">
                  <span class="cell-text">
                    {{ testCase.paramType || 'json' }}
                  </span>
                </div>
                <div class="table-col" :style="{ width: width11 }">
                  <span class="cell-text">
                    {{ testCase.uploadFile || '无' }}
                  </span>
                </div>
                <div class="table-col" :style="{ width: width11 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{
                        JSON.stringify(testCase.requestData, null, 2) || '无'
                      }}
                    </template>
                    <span class="cell-text">
                      {{ JSON.stringify(testCase.requestData) || '无' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width12 }">
                  <span class="cell-text">{{ testCase.postSql || '无' }}</span>
                </div>
                <div class="table-col" :style="{ width: width13 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.expectedResponse || '{"code":0}' }}
                    </template>
                    <span class="cell-text">
                      {{ testCase.expectedResponse || '{"code":0}' }}
                    </span>
                    >
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width14 }">
                  <el-tooltip placement="top">
                    <template #content>
                      {{ testCase.expectedResult || '{"code":0}' }}
                    </template>
                    <span class="cell-text">
                      {{ testCase.expectedResult || '{"code":0}' }}
                    </span>
                  </el-tooltip>
                </div>
                <div class="table-col" :style="{ width: width15 }">
                  <div class="action-buttons">
                    <el-button-group>
                      <el-button
                        size="small"
                        type="primary"
                        @click="startCase(testCase)"
                        title="执行用例"
                        style="border-radius: 8px"
                      >
                        <el-icon><Position /></el-icon>
                      </el-button>
                      <el-button
                        size="small"
                        type="primary"
                        @click="editCase(testCase)"
                        title="编辑"
                        style="border-radius: 8px"
                      >
                        <el-icon><Edit /></el-icon>
                      </el-button>
                      <el-button
                        size="small"
                        type="danger"
                        @click="deleteCase(testCase.id)"
                        title="删除"
                        style="border-radius: 8px"
                      >
                        <el-icon><Delete /></el-icon>
                      </el-button>

                      <el-button
                        type="primary"
                        :icon="CopyDocument"
                        size="small"
                        @click="copyCase(testCase)"
                        style="border-radius: 8px"
                      />
                      <el-button
                        size="small"
                        type="primary"
                        @click="exportCurl(testCase)"
                        title="curl"
                        style="border-radius: 8px"
                      >
                        curl
                      </el-button>
                      <el-button
                        size="small"
                        :disabled="index === 0"
                        @click="moveCase(index, index - 1)"
                        title="上移"
                        style="
                          border-radius: 8px;
                          color: red;
                          font: 1.5em sans-serif;
                        "
                        v-if="moveStatus"
                      >
                        🔺
                        <!-- <el-icon><ArrowUp /></el-icon> -->
                      </el-button>
                      <el-button
                        size="small"
                        :disabled="index === testCases.length - 1"
                        @click="moveCase(index, index + 1)"
                        title="下移"
                        style="
                          border-radius: 8px;
                          color: red;
                          font: 1.5em sans-serif;
                        "
                        v-if="moveStatus"
                      >
                        🔻
                        <!-- <el-icon><ArrowDown /></el-icon> -->
                      </el-button>
                    </el-button-group>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 编辑用例弹窗 -->
    <el-dialog
      v-model="showEditDialog"
      :title="`编辑接口测试用例 - ${getMethodName(editingCase?.method)}`"
      width="900px"
      class="api-case-dialog"
      @close="cancelEdit"
      draggable
      :close-on-click-modal="false"
      top="1vh"
    >
      <el-form :model="formData" label-width="120px" class="form-grid">
        <!-- 第一行：基础信息 -->
        <el-form-item label="用例描述" class="full-width">
          <el-input
            v-model="formData.description"
            placeholder="例如：获取AccessToken"
          />
        </el-form-item>

        <el-form-item label="用例模块">
          <el-input v-model="formData.module" placeholder="例如：概述" />
        </el-form-item>

        <el-form-item label="用例标题">
          <el-input v-model="formData.title" placeholder="例如：接口测试" />
        </el-form-item>

        <!-- 第二行：接口信息 -->
        <el-form-item label="接口地址" class="full-width">
          <el-input
            v-model="formData.apiUrl"
            placeholder="/api/...（表示可变路径参数）"
          />
        </el-form-item>

        <el-form-item label="是否执行">
          <el-select v-model="formData.enabled" class="form-select">
            <el-option :value="true" label="是" />
            <el-option :value="false" label="否" />
          </el-select>
        </el-form-item>

        <el-form-item label="Token操作">
          <el-select v-model="formData.tokenOperation" class="form-select">
            <el-option value="写" />
            <el-option value="读" />
            <!-- <el-option value="自动获取" /> -->
          </el-select>
        </el-form-item>

        <!-- 第三行：请求配置 -->
        <el-form-item label="特殊请求头" class="full-width">
          <el-input
            v-model="formData.specialHeaders"
            type="textarea"
            :rows="2"
            placeholder='{"x-asm-prefer-tag":"sl-test-1"}'
          />
        </el-form-item>

        <el-form-item label="入参关键字">
          <el-select v-model="formData.paramType" class="form-select">
            <el-option value="json" />
            <!-- <el-option value="form" /> -->
            <el-option value="params" />
            <el-option value="data" />
          </el-select>
        </el-form-item>

        <el-form-item label="上传文件">
          <el-input
            v-model="formData.uploadFile"
            placeholder="文件参数对象路径"
          />
        </el-form-item>

        <!-- 第四行：请求数据 -->
        <el-form-item label="请求数据" class="full-width">
          <el-input
            v-model="requestDataJson"
            type="textarea"
            :rows="8"
            placeholder="输入JSON格式的请求数据"
          />
        </el-form-item>

        <!-- 第五行：后置操作 -->
        <el-form-item label="后置SQL" class="full-width">
          <el-input
            v-model="formData.postSql"
            placeholder="执行后需要运行的SQL语句"
          />
        </el-form-item>

        <!-- 第六行：预期结果 -->
        <el-form-item label="预期响应">
          <el-input
            v-model="formData.expectedResponse"
            type="textarea"
            :rows="3"
            placeholder='{"code":0,"msg":"success"}'
          />
        </el-form-item>

        <el-form-item label="预期结果">
          <el-input
            v-model="formData.expectedResult"
            type="textarea"
            :rows="3"
            placeholder='{".code":0}'
          />
        </el-form-item>

        <!-- 第七行：超时设置 -->
        <el-form-item label="超时时间(ms)">
          <el-input-number
            v-model="formData.timeout"
            :min="0"
            :step="1000"
            placeholder="30000"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancelEdit">取消</el-button>
          <el-button type="primary" @click="handleCaseSave">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 数据预览弹窗 -->
    <el-dialog v-model="showDataPreview" title="接口测试用例数据" width="800px">
      <el-input
        v-model="showData"
        type="textarea"
        :rows="24"
        placeholder=""
        disabled
      />
      <template #footer>
        <el-button @click="copyData">复制数据</el-button>
        <el-button type="primary" @click="downloadData">下载JSON</el-button>
      </template>
    </el-dialog>
    <!-- 导入数据-->
    <el-dialog
      v-model="importDataStatus"
      title="导入接口测试用例数据"
      width="800px"
    >
      <el-form>
        <el-form-item label="用例" style="width: 100%">
          <el-input
            v-model="importData"
            type="textarea"
            :rows="24"
            placeholder=""
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="generateImportData(false)">导入所有数据</el-button>
        <el-button @click="generateImportData(true)">导入curl</el-button>
      </template>
    </el-dialog>
    <!-- 发送请求弹窗 -->
    <el-dialog
      v-model="showApiDialog"
      :title="`${formApiData.title}-${formApiData.method}请求`"
      width="900px"
      class="api-case-dialog"
      draggable
      top="1vh"
    >
      <el-form :model="formApiData" label-width="120px" :inline="true">
        <!-- 第一行：URL信息 -->
        <el-row>
          <el-form-item label="请求URL" style="width: 100%">
            <el-input v-model="formApiData.apiUrl" placeholder="请求URL" />
          </el-form-item>
        </el-row>
        <el-row>
          <el-form-item label="获取token">
            <el-input placeholder="请输入手机号" v-model="phone" />
          </el-form-item>
          <el-form-item>
            <el-button type="success" @click="getToken">
              Authorization
            </el-button>
          </el-form-item>
        </el-row>
        <el-row>
          <el-form-item label="请求头" style="width: 100%">
            <el-input
              v-model="formApiData.specialHeaders"
              type="textarea"
              :rows="8"
              placeholder="输入JSON格式的请求头"
            />
          </el-form-item>
        </el-row>
        <el-row>
          <el-form-item label="请求参数" style="width: 100%">
            <el-input
              v-model="formApiData.requestData"
              type="textarea"
              :rows="8"
              placeholder="输入JSON格式的请求数据"
            />
          </el-form-item>
        </el-row>
        <el-row>
          <el-form-item label="响应结果" style="width: 100%">
            <el-input
              v-model="formApiData.resData"
              type="textarea"
              :rows="8"
              placeholder=""
              disabled
            />
          </el-form-item>
        </el-row>
        <el-form-item style="display: flex">
          <el-button type="primary" @click="startApi" style="margin-left: auto">
            请求
          </el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
    
    <script setup >
import { ref, reactive, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import useLayOutSettingStore from '@/store/modules/setting'
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
import apiEnvStore from '@/store/modules/api_env'
import { copyString } from '@/utils/common'
import emmit from '@/utils/emitter'
import {
  reqPostApiCaseModule,
  reqGetOneApiCaseModule,
  reqPutApiCaseModule,
  reqPostImportCurl,
  reqPostExportCurl,
} from '@/api/api_auto/api_case_module'
import {
  Edit,
  Delete,
  ArrowUp,
  ArrowDown,
  CopyDocument,
} from '@element-plus/icons-vue'
import axios from 'axios'
import { reqGetOneApiPreject } from '@/api/api_auto/project'
defineOptions({
  name: 'InterfaceCase1',
})
// 标题
let title_status = ref(false)
// 响应式数据
const title = ref('待修改的模块名称')
const testCases = ref([])
const showEditDialog = ref(false)
const showApiDialog = ref(false)
const editingCase = ref(null)
const isDragOver = ref(false)
const showDataPreview = ref(false)
//宽度

let width1 = '80px'
let width2 = '100px'
let width3 = '100px'
let width4 = '100px'
let width5 = '100px'
let width6 = '60px'
let width7 = '60px'
let width8 = '100px'
let width9 = '80px'
let width10 = '80px'
let width11 = '80px'
let width12 = '80px'
let width13 = '100px'
let width14 = '100px'
let width15 = '300px'
//手机号
let phone = ref(18818880000)
// 表单数据
const formData = ref({})
const formApiData = ref({})
const requestDataJson = ref('')

// HTTP方法定义
const httpMethods = ref()

// 监听编辑用例变化
watch(
  () => editingCase.value,
  (newCase) => {
    if (newCase) {
      formData.value = { ...newCase }
      requestDataJson.value =
        typeof newCase.requestData === 'object'
          ? JSON.stringify(newCase.requestData, null, 2)
          : newCase.requestData || ''
    }
  },
)

// 工具函数
const getMethodName = (method) => {
  const methods = {
    get: 'GET',
    post: 'POST',
    put: 'PUT',
    delete: 'DELETE',
  }
  return methods[method] || method
}

// 拖拽事件
const onDragStart = (method) => {
  isDragOver.value = true
  event.dataTransfer.setData('text/plain', method.type)
}

const onDragEnd = () => {
  isDragOver.value = false
}

const onDragOver = (e) => {
  e.preventDefault()
  isDragOver.value = true
}

const onDragLeave = () => {
  isDragOver.value = false
}

const onDrop = (e) => {
  e.preventDefault()
  isDragOver.value = false

  const methodType = event.dataTransfer.getData('text/plain')
  const method = httpMethods.value.find((m) => m.type === methodType)

  if (method) {
    createNewCase(method)
  }
}
const copyCase = (copy_case) => {
  const caseCopy = { ...copy_case }
  caseCopy.caseId = `case_${String(testCases.value.length + 1).padStart(
    3,
    '0',
  )}`
  testCases.value.push(caseCopy)
}
// 创建用例管理
const createNewCase = (method, opendilog = true) => {
  editingCase.value = {
    caseId: `case_${String(testCases.value.length + 1).padStart(3, '0')}`,
    id: Date.now(),
    method: method.type,
    module: method.data.module,
    description: method.data.description,
    title: method.data.title,
    apiUrl: method.data.apiUrl,
    enabled: method.data.enabled,
    tokenOperation: method.data.tokenOperation,
    specialHeaders: method.data.specialHeaders,
    paramType: method.type == 'post' ? 'json' : 'params',
    uploadFile: method.data.uploadFile,
    postSql: method.data.postSql,
    expectedResponse: method.data.expectedResponse,
    expectedResult: method.data.expectedResult,
    requestData: method.data.requestData,
    timeout: method.data.timeout,
  }
  if (opendilog) {
    showEditDialog.value = true
  }
}

const editCase = (testCase) => {
  editingCase.value = { ...testCase }
  showEditDialog.value = true
}
const startCase = (testCase) => {
  console.log(testCase)
  formApiData.value = { ...testCase }
  formApiData.value.requestData = JSON.stringify(testCase.requestData, null, 2)
  formApiData.value.resData = ''
  let caseHeader = JSON.parse(testCase.specialHeaders)
  caseHeader.Authorization = ''
  formApiData.value.specialHeaders = JSON.stringify(caseHeader, null, 2)
  showApiDialog.value = true
}
const getToken = () => {
  if (!phone.value) {
    ElMessage.error('请输入手机号')
    return
  }
  axios
    .post(
      'http://test.nimiproject.com' + '/api/ms/v1/nimi/login',
      {
        auth_code: (phone.value + '')[(phone.value + '').length - 1],
        device_id: '185ae413009a8ac1',
        phone_number: '+86 ' + phone.value,
      },
      {
        params: {
          loc: 'PH',
          'device-id': '185ae413009a8ac1',
          version: '2.46.2',
          lang: 'zh',
          platform: 'android',
          model: 'RMX2117',
          os: '31',
        },
        headers: {
          'x-asm-prefer-tag': 'sl-test-1',
          Authorization: '',
        },
      },
    )
    .then((response) => {
      console.log(response.data)
      let header = JSON.parse(formApiData.value.specialHeaders)
      header.Authorization =
        'Bearer ' + response.data.data.jwt_token.access_token
      formApiData.value.specialHeaders = JSON.stringify(header, null, 2)
    })
    .catch((error) => {
      console.error(error)
    })
}
const startApi = () => {
  if (!formApiData.value.apiUrl?.trim()) {
    ElMessage.error('请输入接口地址')
    return
  }
  // 处理请求参数
  try {
    if (formApiData.value.requestData.trim()) {
      JSON.parse(formApiData.value.requestData)
    }
  } catch (error) {
    ElMessage.error('请求参数格式错误，请输入有效的JSON')
    return
  }
  if (formApiData.value.method == 'post') {
    // 使用 axios 发起 POST 请求
    axios
      .post(
        'http://test.nimiproject.com' + formApiData.value.apiUrl,
        JSON.parse(formApiData.value.requestData),
        {
          params: {
            loc: 'PH',
            'device-id': '185ae413009a8ac1',
            version: '2.46.2',
            lang: 'zh',
            platform: 'android',
            model: 'RMX2117',
            os: '31',
          },
          headers: JSON.parse(formApiData.value.specialHeaders),
        },
      )
      .then((response) => {
        console.log(response.data)
        formApiData.value.resData = JSON.stringify(response.data, null, 2)
      })
      .catch((error) => {
        console.error(error)
      })
  } else if (formApiData.value.method == 'get') {
    // 使用 axios 发起 GET 请求(推荐)
    axios
      .get('http://test.nimiproject.com' + formApiData.value.apiUrl, {
        params: JSON.parse(formApiData.value.requestData), // 查询参数
        headers: JSON.parse(formApiData.value.specialHeaders),
      })
      .then((response) => {
        formApiData.value.resData = JSON.stringify(response.data, null, 2)
        console.log(response.data)
      })
      .catch((error) => {
        formApiData.value.resData = error + '\n' + error.response.data
        console.error(error)
      })
  }
}
const handleCaseSave = () => {
  if (!formData.value.description?.trim()) {
    ElMessage.error('请输入用例描述')
    return
  }

  if (!formData.value.apiUrl?.trim()) {
    ElMessage.error('请输入接口地址')
    return
  }

  // 处理请求数据
  try {
    if (requestDataJson.value.trim()) {
      formData.value.requestData = JSON.parse(requestDataJson.value)
    } else {
      formData.value.requestData = {}
    }
  } catch (error) {
    ElMessage.error('请求数据格式错误，请输入有效的JSON')
    return
  }

  // 处理特殊请求头
  try {
    if (formData.value.specialHeaders.trim()) {
      JSON.parse(formData.value.specialHeaders)
    }
  } catch (error) {
    ElMessage.error('特殊请求头格式错误，请输入有效的JSON')
    return
  }

  const updatedCase = { ...formData.value }
  const index = testCases.value.findIndex((item) => item.id === updatedCase.id)

  if (index >= 0) {
    testCases.value.splice(index, 1, updatedCase)
  } else {
    testCases.value.push(updatedCase)
  }
  console.log(testCases.value)
  showEditDialog.value = false
  editingCase.value = null
  ElMessage.success('用例保存成功')
}

const cancelEdit = () => {
  showEditDialog.value = false
  editingCase.value = null
}

const deleteCase = async (caseId) => {
  try {
    await ElMessageBox.confirm('确定要删除这个测试用例吗？', '提示', {
      type: 'warning',
    })
    const index = testCases.value.findIndex((item) => item.id === caseId)
    if (index >= 0) {
      testCases.value.splice(index, 1)
      ElMessage.success('用例删除成功')
    }
  } catch (error) {
    // 用户取消删除
  }
}
let moveStatus = ref(false)
const moveCase = (fromIndex, toIndex) => {
  let fromCaseId = testCases.value[fromIndex].caseId
  let toCaseId = testCases.value[toIndex].caseId
  if (toIndex >= 0 && toIndex < testCases.value.length) {
    const [testCase] = testCases.value.splice(fromIndex, 1)

    testCase.caseId = toCaseId //变为移动前，目标位置caseId
    testCases.value.splice(toIndex, 0, testCase)
    testCases.value[fromIndex].caseId = fromCaseId //变为移动前，起始位置caseId
  }
}

const handleReset = async () => {
  try {
    await ElMessageBox.confirm('确定要重置所有测试用例吗？', '提示', {
      type: 'warning',
    })
    testCases.value = []
    ElMessage.success('重置成功')
  } catch (error) {
    // 用户取消重置
  }
}

const handleSave = async () => {
  ElMessageBox.confirm(
    `确定${route.query.caseModuleId ? '修改' : '保存'}所有用例吗？`,
    `${route.query.caseModuleId ? '修改用例' : '保存用例'}`,
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'success',
      //自定义图标
      // icon: markRaw(Star),
      //设置draggable属性为true来开启拖拽弹窗能力。 设置 overflow为 true 可以让拖拽范围超出可视区。
      draggable: true,
      overflow: true,
    },
  )
    .then(async () => {
      if (route.query.caseModuleId) {
        let result = await reqPutApiCaseModule(
          route.query.caseModuleId,
          generateExportData(),
        )
        if (result.code == 200) {
          ElMessage.success(result.msg)
          router.push({
            name: 'InterfaceAllCase',
          })
        } else {
          ElMessage.error(result.msg)
        }
      } else {
        let result = await reqPostApiCaseModule(generateExportData())
        if (result.code == 200) {
          ElMessage.success(result.msg)
          router.push({
            name: 'InterfaceAllCase',
          })
        } else {
          ElMessage.error(result.msg)
        }
      }
    })
    .catch(() => {
      ElMessage({
        type: 'info',
        message: '取消操作',
      })
    })
}
function getLocalTimeString() {
  const date = new Date()
  const year = date.getFullYear()
  const month = (date.getMonth() + 1).toString().padStart(2, '0') // 月份从0开始，需加1
  const day = date.getDate().toString().padStart(2, '0')
  const hours = date.getHours().toString().padStart(2, '0')
  const minutes = date.getMinutes().toString().padStart(2, '0')
  const seconds = date.getSeconds().toString().padStart(2, '0')

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
// 数据导出
const generateExportData = () => {
  for (let index = 0; index < testCases.value.length; index++) {
    const element = testCases.value[index]
    element.BaseURL = EnvStore.BaseURL
    element.envVariable = EnvStore.envVariable
  }

  return {
    title: title.value,
    version: '1.0.0',
    updateAt: getLocalTimeString(),
    // testCases: testCases.value.map((testCase, index) => ({
    //   caseId: `case_${String(index + 1).padStart(3, '0')}`,
    //   ...testCase,
    // })),
    testCases: testCases.value,
  }
}
// 数据展示
let showData = ref()
const showDialog = () => {
  showData.value = JSON.stringify(generateExportData(), null, 2)

  showDataPreview.value = true
}

// 数据导入
let importDataStatus = ref(false)
let importData = ref()
const exportCurl = async (row) => {
  let data
  if (row.method == 'get' || row.method == 'put') {
    data = {
      method: row.method,
      url: EnvStore.BaseURL + row.apiUrl,
      headers: JSON.parse(row.specialHeaders),
      params: {},
      form_data: row.requestData,
      json_data: {},
      raw_data: '',
      files: {},
      form_fields: {},
      auth: '',
      verify: '',
      cookies: '',
      binary_file: '',
      baseURL: EnvStore.BaseURL,
    }
  } else {
    data = {
      method: row.method,
      url: EnvStore.BaseURL + row.apiUrl,
      headers: JSON.parse(row.specialHeaders),
      params: {},
      form_data: {},
      json_data: row.requestData,
      raw_data: '',
      files: {},
      form_fields: {},
      auth: '',
      verify: '',
      cookies: '',
      binary_file: '',
      baseURL: EnvStore.BaseURL,
    }
  }

  let result = await reqPostExportCurl(data)
  if (result.code == 200) {
    // ElMessage.success(result.msg)
    copyString(result.data.curl_string)
  } else {
    ElMessage.error(result.msg)
  }
}
const generateImportData = async (curl_status) => {
  if (curl_status) {
    let result = await reqPostImportCurl(importData.value)
    if (result.code == 200) {
      let curl_data = {
        caseId: `case_${String(testCases.value.length + 1).padStart(3, '0')}`,
        id: Date.now(),
        method: result.data.method.toLowerCase(),
        module: '模块',
        description: '描述',
        title: '标题',
        apiUrl: result.data.url.replace(EnvStore.BaseURL, ''),
        enabled: true,
        tokenOperation: '读',
        specialHeaders: '{"x-asm-prefer-tag":"sl-test-1"}',
        paramType:
          result.data.method.toLowerCase() == 'post' ? 'json' : 'params',
        uploadFile: '',
        postSql: '',
        expectedResponse: '{"code":0}',
        expectedResult: '{"code":0}',
        requestData: result.data.json_data,
        timeout: 30000,
      }
      testCases.value.push(curl_data)
      ElMessage.success(result.msg)
      importDataStatus.value = false
    } else {
      ElMessage.error(result.msg)
    }
  } else {
    try {
      await ElMessageBox.confirm(
        '确定要导入测试用例吗？将会覆盖所有用例',
        '提示',
        {
          type: 'warning',
        },
      )
      if (!importData.value) {
        ElMessage({
          type: 'info',
          message: '不能为空',
        })
        return
      }

      try {
        testCases.value = JSON.parse(importData.value).testCases
      } catch (error) {
        ElMessage({
          type: 'error',
          message: '数据格式错误',
        })
        return
      }

      console.log(testCases.value)
      ElMessage.success('导入成功')
      importDataStatus.value = false
    } catch (error) {
      // 用户取消重置
      ElMessage({
        type: 'info',
        message: '取消操作',
      })
    }
  }

  // return {
  //   title: title.value,
  //   version: '1.0.0',
  //   updateAt: getLocalTimeString(),

  //   testCases: testCases.value,
  // }
}

const copyData = async () => {
  try {
    await navigator.clipboard.writeText(
      JSON.stringify(generateExportData(), null, 2),
    )
    ElMessage.success('数据已复制到剪贴板！')
  } catch (err) {
    ElMessage.error('复制失败')
    console.error('复制失败:', err)
  }
}

const downloadData = () => {
  const dataStr = JSON.stringify(generateExportData(), null, 2)
  const dataBlob = new Blob([dataStr], { type: 'application/json' })
  const url = URL.createObjectURL(dataBlob)
  const link = document.createElement('a')
  link.href = url
  link.download = `api_test_cases_${Date.now()}.json`
  link.click()
  URL.revokeObjectURL(url)
  ElMessage.success('数据下载成功')
}
//获取的数据
//组件挂载完毕操作
let EnvStore = apiEnvStore()
const router = useRouter()
const envData = async (env_data) => {
  if (env_data.envId != 0) {
    console.log(env_data.envComponent.other)
    httpMethods.value = [
      ...env_data.envComponent.main,
      ...env_data.envComponent.other,
    ]
    httpMethods.value.push()
    return
  }
  let envId = localStorage.getItem('envId')
  if (envId) {
    let result = await reqGetOneApiPreject(parseInt(envId))
    if (result.code == 200) {
      EnvStore.envName = result.data.envProjectName
      EnvStore.BaseURL = result.data.BaseURL
      EnvStore.envId = result.data.id
      EnvStore.envVariable = JSON.parse(result.data.envVariable)
      EnvStore.envComponent = JSON.parse(result.data.envComponent)
      httpMethods.value = [
        ...EnvStore.envComponent.main,
        ...EnvStore.envComponent.other,
      ]
      httpMethods.value.push()
    } else {
      ElMessage.error(result.msg)
    }
  }
}
const caseModuleData = async (casesId, case_module_id) => {
  if (case_module_id) {
    casesId = case_module_id
  }
  if (casesId) {
    console.log(casesId)
    let result = await reqGetOneApiCaseModule(casesId)
    if (result.code == 200) {
      // ElMessage.success(result.msg)
      testCases.value = result.data.allCaseData
      title.value = result.data.caseModuleName
    } else {
      ElMessage.error(result.msg)
    }
  }
}
const route = useRoute()
onMounted(() => {
  if (!localStorage.getItem('envId')) {
    ElMessage.error('你还没选择项目')
    router.push({
      name: 'InterfaceEnv',
    })
    return
  }
  // createNewCase(httpMethods.value[1], false)

  envData(EnvStore)

  caseModuleData(route.query.caseModuleId, EnvStore.case_module_id)
  // testCases.value.push(editingCase.value)
})
let LayOutSettingStore = useLayOutSettingStore()
onBeforeRouteLeave(async (to, from, next) => {
  emmit.emit('beforeTabLeave')
  try {
    await ElMessageBox.confirm(
      '确定要离开此页面吗？未保存的更改可能会丢失。',
      '提示',
      {
        type: 'warning',
        confirmButtonText: '确定离开',
        cancelButtonText: '取消',
      },
    )
    // 用户点击了“确定离开”，执行下一步路由跳转
    next()
    emmit.emit('beforeTabLeave')
  } catch (error) {
    // 用户点击了“取消”，中断本次路由跳转，停留在当前页面
    emmit.emit('beforeTabLeave')
    next(false)
  }
})
</script>
    
    <style scoped lang="scss">
.header-left {
  display: flex;
  justify-content: space-between;
}
.api-test-editor {
  display: flex;
  flex-direction: column;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.hollow-text.gentle-blue {
  font-size: 16px;
  font-weight: 700;
  color: transparent;
  -webkit-text-stroke: 1.2px rgba(64, 158, 255, 0.9);
  letter-spacing: 1.5px;
  text-shadow: 0 0 8px rgba(64, 158, 255, 0.4), 0 0 15px rgba(64, 158, 255, 0.2);
  text-transform: uppercase;
  font-family: 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
  padding: 5px 12px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(24, 144, 255, 0.2),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5);
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.hollow-text.gentle-blue:hover {
  -webkit-text-stroke: 1.5px rgba(24, 144, 255, 1);

  text-shadow: 0 0 12px rgba(24, 144, 255, 0.5),
    0 0 25px rgba(24, 144, 255, 0.3);
  transform: translateY(-1px);
}
/* 头部样式 */
.header {
  height: 60px;

  border-bottom: 1px solid #e1e8ed;
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-shadow: 0 1px 3px 3px rgba(0, 0, 0, 0.15);
}

.title {
  margin: 0;

  font-size: 18px;
  font-weight: 600;
}

.header-right {
  display: flex;
  gap: 12px;
}

/* 主内容区 */
.main-content {
  flex: 1;
  display: flex;
  overflow: hidden;
}

/* 侧边栏 */
.sidebar {
  width: 150px;

  border-right: 1px solid #e1e8ed;
  padding: 20px 0;
}

.sidebar-section {
  margin-bottom: 20px;
}

.section-header {
  padding: 12px 20px;
  font-weight: 600;
  color: #333;
  border-bottom: 1px solid #f0f0f0;
  margin-bottom: 10px;
}

.section-content {
  box-shadow: 3px 0px rgba(0, 0, 0, 0.15);
  padding: 0 10px;
}

.method-item {
  padding: 12px 16px;
  margin: 8px 0;
  border-radius: 6px;
  cursor: grab;
  display: flex;
  align-items: center;
  gap: 10px;
  transition: all 0.3s;
  border: 2px solid transparent;
}

.method-item:hover {
  transform: translateX(5px);
}

.method-item.get {
  border-color: #b3d4ff;
}

.method-item.post {
  border-color: #a3e9cb;
}

.method-item.put {
  border-color: #ffd591;
}

.method-item.delete {
  border-color: #ffbbb7;
}

.method-item:active {
  cursor: grabbing;
}

.method-icon {
  font-size: 16px;
}

.method-name {
  color: #333 !important;
  font-weight: 500;
  font-size: 14px;
}

/* 内容区域 */
.content {
  flex: 1;
  padding: 20px;
  overflow: auto;
}

.drop-zone {
  /* background: white; */
  /* border: 2px dashed #d9d9d9; */
  max-width: max(1250px, calc(100vw - 440px));
  border-radius: 10px;
  min-height: 400px;
  transition: all 0.3s;
  position: relative;
  padding: 10px;
  box-shadow: inset 0 0 10px 1px rgb(217 216 216);
}
.drop-zone.folded {
  max-width: max(1250px, calc(100vw - 290px)); /* 折叠状态 */
}
.drop-zone.drag-over {
  border-color: #1890ff;
  background: #f0f7ff;
}

.zone-label {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  color: #999;
}

.label-icon {
  font-size: 48px;
  margin-bottom: 12px;
  opacity: 0.5;
}

.label-text {
  font-size: 16px;
}

/* 表格样式 */
.cases-table {
  width: 100%;
  background: white;
}

.table-header {
  display: flex;
  background: #fafafa;
  border: 2px solid #a3d8a0;
  font-weight: 600;
  color: #333;
  font-size: 13px;
  margin-bottom: 10px;
}

.table-row {
  display: flex;
  border: 1px dashed #03c9c9;
  transition: background-color 0.2s;
  margin-bottom: 10px;
  border-radius: 20px;
  box-shadow: inset 0 0 5px #d9d8d8;
  /* background: rgb(240, 249, 245, 0.6); */
}

.table-row:hover {
  background: #f0f7ff;
}

.table-col {
  padding: 12px 8px;
  border-right: 1px dashed #a3d8a0;
  display: flex;
  align-items: center;
  min-height: 44px;
  box-sizing: border-box;
  overflow: hidden;
  min-width: 0;
}

.table-col:last-child {
  border-right: none;
}

.cell-text {
  font-size: 12px;
  color: #333 !important;
  line-height: 1.4;
  word-break: break-all;
  display: block;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  transition: all 0.2s;
}
.cell-text1 {
  font-size: 12px;
  color: #333 !important;
  line-height: 1.4;
  word-break: break-all;
  display: block;
  width: 100%;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  transition: all 0.2s;
}

.cell-text.url {
  color: #1890ff;
  font-family: 'Courier New', monospace;
}

.cell-text.method {
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 11px;
  font-weight: 600;
  color: white;
}

.cell-text.method.get {
  background: #61affe;
}

.cell-text.method.post {
  background: #49cc90;
}

.cell-text.method.put {
  background: #fca130;
}

.cell-text.method.delete {
  background: #f93e3e;
}

/* 操作按钮 */
.action-buttons {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}

/* 表单样式 */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}

.form-grid .el-form-item {
  margin-bottom: 16px;
}

.form-grid .full-width {
  grid-column: 1 / -1;
}

/* 预览内容 */
.preview-content {
  background: #fafafa;
  padding: 16px;
  border-radius: 4px;
  max-height: 400px;
  overflow: auto;
}

.preview-content pre {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
  font-family: 'Courier New', monospace;
}

/* 弹窗样式优化 */
:deep(.api-case-dialog .el-dialog__body) {
  padding: 20px;
}

:deep(.api-case-dialog .el-form-item__label) {
  font-weight: 500;
}
</style>